using Infrastructure.Attribute;
using Infrastructure.Extensions;
using JTZY.Model.Order.Dto;
using JTZY.Model.Order;
using JTZY.Repository;
using JTZY.Service.Order.IOrderService;
using JTZY.Model.Business;
using System.Diagnostics.Metrics;
using JTZY.Model.Goods;
using JTZY.Model.Product;
using Microsoft.AspNetCore.Http;
using Infrastructure;
using System.Reflection.Metadata.Ecma335;
using Infrastructure.Enums;
using JTZY.Service.Pay.IPayService;
using JTZY.Service.Pay;
using static StackExchange.Redis.Role;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel;
using System;
using JTZY.Infrastructure.Enums;
using Org.BouncyCastle.Asn1.X9;
using static JTZY.Common.GlobalEnumVars;
using JTZY.Common;
using StackExchange.Redis;
using Org.BouncyCastle.Crypto;
using JTZY.Model.Brand;
using Mapster;
using JTZY.Service.Goods.IGoodsService;
using JTZY.Service.Goods;
using MailKit.Search;
using JTZY.Service.Business.IBusinessService;

namespace JTZY.Service.Order
{
    /// <summary>
    /// 订单表Service业务层处理
    /// </summary>
    [AppService(ServiceType = typeof(ICorecmsorderService), ServiceLifetime = LifeTime.Transient)]
    public class CorecmsorderService : BaseService<Corecmsorder>, ICorecmsorderService
    {
        private readonly ICorecmsbillaftersalesService _billAftersalesServices;
        private readonly ICorecmsorderitemService _orderItemServices;
        private readonly ICorecmsbillaftersalesitemService _billAftersalesItemServices;
        private readonly ICorecmsbillrefundService _billRefundServices;
        private readonly ICorecmsorderlogService _orderLogServices;
        private readonly ICorecmsbillpaymentsService _billPaymentsServices;
        private readonly IRedisOperationRepository _redisOperationRepository;
        private readonly ICorecmsbilldeliveryService _billDeliveryServices;
        private readonly IOrderdetailService _orderdetailService;
        private readonly IBillaftersaledetailService _billaftersaledetailService;
        private readonly ICorecmsgoodsService _corecmsgoodsService;
        private readonly ICorecmsuserService _corecmsuserService;
        public CorecmsorderService(ICorecmsbillaftersalesService billAftersalesServices
            , ICorecmsbillaftersalesitemService billAftersalesItemServices
            , ICorecmsbillrefundService billRefundServices
            , ICorecmsbillpaymentsService billPaymentsServices
            , ICorecmsorderlogService orderLogServices
            , IRedisOperationRepository redisOperationRepository
            , ICorecmsbilldeliveryService billDeliveryServices
            , IOrderdetailService orderdetailService
            , IBillaftersaledetailService billaftersaledetailService
            , ICorecmsgoodsService corecmsgoodsService
            , ICorecmsuserService corecmsuserService
            , ICorecmsorderitemService orderItemServices)
        {
            _billAftersalesServices = billAftersalesServices;
            _orderItemServices = orderItemServices;
            _billAftersalesItemServices = billAftersalesItemServices;
            _billRefundServices = billRefundServices;
            _billPaymentsServices = billPaymentsServices;
            _orderLogServices = orderLogServices;
            _redisOperationRepository = redisOperationRepository;
            _billDeliveryServices = billDeliveryServices;
            _orderdetailService = orderdetailService;
            _billaftersaledetailService = billaftersaledetailService;
            _corecmsgoodsService = corecmsgoodsService;
            _corecmsuserService = corecmsuserService;
        }

        /// <summary>
        /// 查询订单表列表
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        public PagedInfo<CorecmsorderDto> GetList(CorecmsorderQueryDto parm)
        {
            var predicate = QueryExp(parm);
            //, item => item.Addon.Contains(parm.skuName)).WhereIF(!string.IsNullOrEmpty(parm.snCode), item => item.SnCodes.Contains(parm.snCode)
            //if (!string.IsNullOrEmpty(parm.skuName))
            //    Context.QueryFilter.AddTableFilter<Corecmsorderitem>(x => x.Addon == parm.skuName);
            //if (!string.IsNullOrEmpty(parm.snCode))SqlFunc.Subqueryable<Order>() .Where(o => o.UserId == u.Id).Any()
            //    Context.QueryFilter.AddTableFilter<Corecmsorderitem>(x => x.SnCodes.Contains(parm.snCode));

            var response = Queryable()
                .InnerJoin<Corecmsuser>((it, custer) => it.UserId == custer.Id)
                .WhereIF(parm.orderType == 1, (it, custer) => custer.ParentId == parm.userId)
                .WhereIF(!string.IsNullOrEmpty(parm.userName), (it, custer) => custer.UserName.Contains(parm.userName))
                .WhereIF(parm.orderType == 11, (it, custer) => it.UserId == parm.userId)
                .WhereIF(parm.queryType == "1", (it, custer) => it.Status != 0 && it.Status != 1&&it.IsMini==0)
                .WhereIF(parm.isMini.HasValue, (it, custer) => it.IsMini == parm.isMini)
                .WhereIF(!string.IsNullOrEmpty(parm.skuName), (it, custer) => SqlFunc.Subqueryable<Corecmsorderitem>().Where(item => item.OrderId == it.OrderId && item.Addon.Contains(parm.skuName)).Any())
                .WhereIF(!string.IsNullOrEmpty(parm.snCode), (it, custer) => SqlFunc.Subqueryable<Orderdetail>().Where(item => item.OrderId == it.OrderId && item.SnCode == parm.snCode).Any())
                .Select((it, custer) => new Corecmsorder
                {
                    OrderId = it.OrderId,
                    OrderAmount = it.OrderAmount,
                    UserId = it.UserId,
                    UserName = custer.UserName,
                    CreateTime = it.CreateTime,
                    Status = it.Status,
                    PayStatus = it.PayStatus,
                    ReceiptType = it.ReceiptType,
                    IsMini = it.IsMini,
                })
                //导航查询 属性过滤
                .Includes(x => x.CorecmsorderitemNav)
                .Where(predicate.ToExpression()).OrderByDescending(it => new { it.CreateTime })
                .ToPage<Corecmsorder, CorecmsorderDto>(parm);


            var goodsIds = response.Result.SelectMany(e => e.CorecmsorderitemNav.Select(e => e.GoodsId)).ToList();
            // 获取商品和品牌的映射关系
            var goodsBrandMap = Context.Queryable<Corecmsgoods>()
                .LeftJoin<Corecmsbrand>((goods, brand) => goods.BrandId == brand.Id)
                .Where(goods => goodsIds.Contains(goods.Id))
                .Select((goods, brand) => new
                {
                    GoodsId = goods.Id,
                    BrandName = brand.Name
                })
                .ToList()
                .ToDictionary(x => x.GoodsId, x => x.BrandName);

            // 补全 CorecmsorderitemNav 的 BrandName
            foreach (var orderDto in response.Result)
            {
                foreach (var orderItem in orderDto.CorecmsorderitemNav)
                {
                    if (goodsBrandMap.TryGetValue(orderItem.GoodsId, out var brandName))
                    {
                        orderItem.BrandName = brandName;
                    }
                    if (!string.IsNullOrEmpty(orderItem.SnCodes)) 
                    {
                        orderItem.SnCodes = orderItem.SnCodes.Replace(",", " ").Replace("\"","").Replace("[","").Replace("]","");
                    }
                }
            }

            return response;
        }


        /// <summary>
        /// 获取详情
        /// </summary>
        /// <param name="OrderId"></param>
        /// <returns></returns>
        public Corecmsorder GetInfo(string OrderId)
        {
            var response = Queryable()
                .Includes(x => x.CorecmsorderitemNav) //填充子对象
                .Where(x => x.OrderId == OrderId)
                .First();

            return response;
        }

        /// <summary>
        /// 添加订单表
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public Corecmsorder AddCorecmsorder(Corecmsorder model)
        {
            return Context.InsertNav(model).Include(s1 => s1.CorecmsorderitemNav).ExecuteReturnEntity();
        }

        /// <summary>
        /// 导出订单表
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        public PagedInfo<CorecmsorderDto> ExportList(CorecmsorderQueryDto parm)
        {
            var predicate = QueryExp(parm);

            var response = Queryable()
                .Where(predicate.ToExpression())
                .Select((it) => new CorecmsorderDto()
                {
                    PayStatusLabel = it.PayStatus.GetConfigValue<Model.System.SysDictData>("pay_status"),
                    StatusLabel = it.Status.GetConfigValue<Model.System.SysDictData>("order_status"),
                    ReceiptTypeLabel = it.ReceiptType.GetConfigValue<Model.System.SysDictData>("receipt_type"),
                }, true)
                .ToPage(parm);

            return response;
        }

        /// <summary>
        /// 确认订单
        /// </summary>
        /// <param name="modal"></param>
        /// <returns></returns>
        public int comfir(Corecmsorder modal, long userId)
        {
            var order = Queryable().Where(order => order.OrderId == modal.OrderId&& order.Status == (int)OrderStatus.Confirm).First();
            if (order == null)
            {
                throw new CustomException("不是有效的订单");
            }
            if (order.PayStatus != 2)
            {
                throw new CustomException("订单未支付");
            }
            if (order.Status == (int)OrderStatus.Cancel)
            {
                throw new CustomException("订单已取消");
            }
            if (order.Status == (int)OrderStatus.Complete)
            {
                throw new CustomException("订单已完成");
            }
            if (order.Status == (int)OrderStatus.pack)
            {
                throw new CustomException("订单已打包过");
            }
            if (order.Status == (int)OrderStatus.send)
            {
                throw new CustomException("订单已发货");
            }
            if (order.IsMini == 1)
            {
                throw new CustomException("小仓单，勿操作");
            }
            var list = _orderItemServices.Queryable()
                .LeftJoin<Corecmsuserstock>((it, us) => it.ProductId == us.ProductId && us.UserId == userId)
                .Where(it => it.OrderId == modal.OrderId)
                .Select((it, us) => new Corecmsorderitem
                {
                    OrderId = it.OrderId,
                    Nums = it.Nums,
                    Addon = !string.IsNullOrEmpty(us.SkuName) ? us.SkuName : it.Addon,
                    Stock = us.Stock != null ? us.Stock.Value : 0,
                    ProductId = it.ProductId
                })
                .ToList();
            foreach (var item in list)
            {
                if (item.Nums > item.Stock)
                {
                    throw new CustomException(item.Addon + "，库存不足");
                }
            }


            return Update(u => u.OrderId == modal.OrderId, it => new Corecmsorder() { Status = modal.Status, UpdateTime = DateTime.Now });

        }

        /// <summary>
        /// 打包
        /// </summary>
        /// <param name="modal"></param>
        /// <returns></returns>
        public WebApiCallBack Pack(OrderPackDto modal)
        {
            var jm = new WebApiCallBack();

            var result = UseTran(() =>
            {
                var order = Queryable().Where(o => o.OrderId == modal.orderId).First();
                if (order == null)
                {
                    jm.status = false;
                    jm.msg = "不是有效的订单";
                    return;
                }
                if (order.Status == (int)OrderStatus.Cancel)
                {
                    jm.status = false;
                    jm.msg = "订单已取消";
                    return;
                }
                if (order.Status == (int)OrderStatus.Complete)
                {
                    jm.status = false;
                    jm.msg = "订单已完成";
                    return;
                }
                if (order.Status == (int)OrderStatus.pack)
                {
                    jm.status = false;
                    jm.msg = "订单已打包过";
                    return;
                }
                if (order.Status == (int)OrderStatus.send)
                {
                    jm.status = false;
                    jm.msg = "订单已发货";
                    return;
                }
                if (order.IsMini == 1)
                {
                    jm.status = false;
                    jm.msg = "扫码订单不需要打包出库";
                    return;
                }
                //throw new CustomException("订单不存在");
                order.Status = 4;//商品已打包
                                 //Update(order);
                var orderItems = Context.Queryable<Corecmsorderitem>().Where(p => p.OrderId == modal.orderId).ToList();

                if (orderItems == null)
                {
                    jm.status = false;
                    jm.msg = "订单明细不存在";
                    return;
                }

                if (modal.list == null|| modal.list.Count<=0)
                {
                    jm.status = false;
                    jm.msg = "未检测到出库物码";
                    return;
                }
                //if (orderItems == null) throw new CustomException("订单不存在");

                Update(u => u.OrderId == modal.orderId, it => new Corecmsorder() { Status = order.Status, UpdateTime = DateTime.Now, });

                Context.Deleteable<Orderdetail>().Where(d => d.OrderId == modal.orderId).ExecuteCommand();
                Context.Insertable<Orderdetail>(modal.list).ExecuteCommand();

                orderItems.ForEach(item =>
                {

                    List<string> l = modal.list.Where(d => d.ProductId == item.ProductId).Select(d => d.SnCode).ToList();

                    item.SnCodes = JsonConvert.SerializeObject(l);

                    //_orderItemServices.Update(u => u.Id == item.Id, it => new Corecmsorderitem() { SnCodes = item.SnCodes });
                    Context.Updateable<Corecmsorderitem>().SetColumns(it => new Corecmsorderitem() { SnCodes = item.SnCodes, UpdateTime = DateTime.Now, }).Where(u => u.OrderId == modal.orderId).RemoveDataCache().ExecuteCommand();
                });

                var codes = modal.list.Select(d => d.SnCode).ToList();
                var ProdinfoList = Context.Queryable<Prodinfo>().Where(d => codes.Contains(d.SnCode)).ToList();
                foreach (var prod in ProdinfoList)
                {
                    prod.Status = 2;
                }
                Context.Updateable<Prodinfo>(ProdinfoList).UpdateColumns(it => new { it.Status }).ExecuteCommand();

                jm.status = true;
            });
            jm.data = modal;

            //jm.status = result.IsSuccess;
            //jm.msg = result
            return jm;
        }

        /// <summary>
        /// 发货
        /// </summary>
        /// <param name="modal"></param>
        /// <param name="userId">代理</param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<WebApiCallBack> Ship(Corecmsorder modal, long userId)
        {
            var jm = new WebApiCallBack();
            var order = Queryable().Where(o => o.OrderId == modal.OrderId&&o.Status==4).First();

            var result = UseTran(() =>
            {
                if (order == null) throw new CustomException("订单不存在");
                if (order.Status == 2)
                {
                    throw new CustomException("订单已完成，请勿重复操作");
                }
                if (order.Status == 3)
                {
                    throw new CustomException("订单已取消，请勿重复操作");
                }
                order.Status = 2;//商品发货
                order.SendTime = DateTime.Now;
                if (order.ReceiptType != (int)OrderReceiptType.SelfDelivery)
                {
                    order.DeliveryType = modal.DeliveryType;
                }
                else
                {
                    order.DeliveryType = "";
                }

                //扣减库存
                var orderItemList = Context.Queryable<Corecmsorderitem>().Where(p => p.OrderId == modal.OrderId).ToList();
                var detai = Context.Queryable<Orderdetail>().Where(d => d.OrderId == modal.OrderId).ToList();
                var productIds = orderItemList.Select(oi => oi.ProductId).ToList();
                //Dictionary<int, int> items = new Dictionary<int, int>();
                var userStockList = Context.Queryable<Corecmsuserstock>().Where(p => p.UserId == userId && productIds.Contains(p.ProductId)).ToList();

                foreach (var product in orderItemList)
                {
                    //items.Add(product.ProductId, product.Nums);
                    var us = userStockList.Find(us => us.ProductId == product.ProductId);
                    if (us != null)
                    {
                        us.Stock -= product.Nums;
                        us.SaleStock -= product.Nums;
                        us.SaleQty = (us.SaleQty.HasValue ? us.SaleQty.Value + product.Nums : product.Nums);
                        us.FreezeStock = us.FreezeStock - product.Nums;
                        if (us.FreezeStock < 0) us.FreezeStock = 0;
                    }
                    product.SendNums = product.Nums;
                }

                Context.Updateable<Corecmsuserstock>(userStockList).WhereColumns(it => new { it.Id }).UpdateColumns(it => new { it.Stock, it.SaleStock, it.SaleQty, it.FreezeStock }).ExecuteCommand();

                Context.Updateable<Corecmsorderitem>(orderItemList).WhereColumns(it => new { it.Id }).UpdateColumns(it => new { it.SendNums }).ExecuteCommand();

                var flowList = new List<StockFlowItem>();
                var dt = DateTime.Now;
                //更新产品所属关系
                var codes = detai.Select(d => d.SnCode).ToList();
                var ProdinfoList = Context.Queryable<Prodinfo>().Where(d => codes.Contains(d.SnCode)).ToList();
                foreach (var prod in ProdinfoList)
                {

                    prod.UserCusId = 0;
                    prod.UserId = order.UserId;
                    prod.Status = 2;//出库

                    var item = orderItemList.Where(t => t.ProductId == prod.ProductId).First();
                    var flow = new StockFlowItem();
                    flow.UserId = order.UserId;
                    flow.CreateTime = dt;
                    flow.SheetNo = order.OrderId;
                    flow.SnCode = prod.SnCode;
                    flow.ProductId = prod.ProductId;
                    flow.DbNo = "-";
                    flow.OrderType = 0;
                    flow.Price = item != null ? item.Price : 0;
                    flowList.Add(flow);

                }
                Context.Updateable<Prodinfo>(ProdinfoList).WhereColumns(it => new { it.Id }).UpdateColumns(it => new { it.UserCusId, it.UserId, it.Status }).ExecuteCommand(); 

                //写入库明细
                Context.Insertable<StockFlowItem>(flowList).ExecuteCommand();

                order.ReceiveTime = dt;
                var res = Update(u => u.OrderId == modal.OrderId, it => new Corecmsorder()
                {
                    Status = order.Status,
                    SendTime = order.SendTime,
                    UpdateTime = DateTime.Now,
                    ShipStatus = (int)OrderShipStatus.Yes,
                    ConfirmStatus = 2,
                    ConfirmTime = DateTime.Now,
                    ReceiveTime = order.ReceiveTime,
                    DeliveryType = order.DeliveryType
                });

                // _redisOperationRepository.

            });
            jm.data = modal;
            jm.status = result.IsSuccess;
            jm.msg = result.ErrorMessage;
            if (result.IsSuccess)
            {
                //订单完成结算订单
                await _redisOperationRepository.ListLeftPushAsync(RedisMessageQueueKey.OrderFinishCommand, order.OrderId);
                //订单发货处理
                var paymentInfo = await _billPaymentsServices.Queryable().Where(p => p.SourceId == order.OrderId && p.Status == (int)BillPaymentsStatus.Payed).FirstAsync();
                if (paymentInfo != null)
                {
                    await _redisOperationRepository.ListLeftPushAsync(RedisMessageQueueKey.WeChatPayShipping, paymentInfo.PaymentId);
                }
            }
            return jm;
        }

        /// <summary>
        /// 发货改状态
        /// </summary>
        /// <param name="orderId"></param>
        /// <param name="items"></param>
        /// <returns></returns>
        public async Task<WebApiCallBack> EditShipStatus(string orderId, Dictionary<int, int> items)
        {
            var jm = new WebApiCallBack();

            await UpdateAsync(
                    p => new Corecmsorder() { ShipStatus = (int)OrderShipStatus.Yes, SendTime = DateTime.Now, Status = (int)OrderStatus.Complete },
                    p => p.OrderId == orderId);

            jm.status = true;

            return jm;
        }

        public async Task<WebApiCallBack> GetOrderShipInfo(string orderId)
        {
            var jm = new WebApiCallBack { status = true };

            var orderInfo = await Queryable().Where(p => p.OrderId == orderId).FirstAsync();
            if (orderInfo == null)
            {
                jm.msg = "请选择订单";
                return jm;
            }
            orderInfo.items = await _orderItemServices.Queryable().Where(p => p.OrderId == orderId).ToListAsync();
            var isStoreId = 0;//校验是普通快递收货，还是门店自提，这两种收货方式不能混着发
                              //更改状态和库存

            if (orderInfo.Status != (int)OrderStatus.pack)
            {
                jm.status = false;
                jm.msg = "订单号：" + orderInfo.OrderId + "非正常状态不发货。<br />";
            }
            else if (orderInfo.PayStatus == (int)OrderPayStatus.No)
            {
                jm.status = false;
                jm.msg = "订单号：" + orderInfo.OrderId + "未支付不能发货。<br />";
            }
            else if (orderInfo.ShipStatus != (int)OrderShipStatus.No && orderInfo.ShipStatus != (int)OrderShipStatus.PartialYes)
            {
                jm.status = false;
                jm.msg = "订单号：" + orderInfo.OrderId + "不是待发货和部分发货状态不能发货。<br />";
            }
            //校验，不能普通快递和门店自提，不能混发
            isStoreId = orderInfo.StoreId;

            //判断是否有未审核的售后单，如果有，就不能发货，已做拦截
            var isHaveBillAfterSales = await _billAftersalesServices.Queryable().Where(p =>
                p.OrderId == orderInfo.OrderId &&
                p.Status == (int)BillAftersalesStatus.WaitAudit).AnyAsync();
            if (isHaveBillAfterSales)
            {
                jm.status = false;
                jm.msg = "订单号：" + orderInfo.OrderId + "有未审核的售后单，请先处理掉才能发货。";
                return jm;
            }
            AfterSalesVal(orderInfo, 0);

            if (!jm.status)
            {
                return jm;
            }

            var newOrder = new AdminOrderShipOneResult()
            {
                orderId = orderId,
                weight = orderInfo.Weight,
                costFreight = orderInfo.CostFreight,
                storeId = orderInfo.StoreId,
                shipAreaId = orderInfo.ShipAreaId,
                shipAddress = orderInfo.ShipAddress,
                shipName = orderInfo.ShipName,
                shipMobile = orderInfo.ShipMobile,
                logisticsId = orderInfo.LogisticsId,
                logisticsName = orderInfo.LogisticsName,
                items = new List<Corecmsorderitem>(),
                orderInfo = orderInfo,
                memo = orderInfo.Memo
            };

            //if (newOrder.logisticsId > 0)
            //{
            //    newOrder.ship = await _shipServices.QueryByClauseAsync(p => p.id == newOrder.logisticsId);
            //}

            //组合总运费
            foreach (var orderItem in orderInfo.items)
            {
                var model = newOrder.items.FirstOrDefault(p => p.ProductId == orderItem.ProductId);
                if (model == null)
                {
                    newOrder.items.Add(orderItem);
                }
                else
                {
                    var index = newOrder.items.IndexOf(model);
                    newOrder.items[index].Nums += orderItem.Nums;//总数量
                    newOrder.items[index].Weight += orderItem.Weight;//总重量
                    newOrder.items[index].SendNums += orderItem.SendNums;//已发送数量
                    newOrder.items[index].reshipNums += orderItem.reshipNums;//退货数量
                }
            }

            jm.status = true;
            jm.data = newOrder;

            return jm;
        }


        public WebApiCallBack Take(Corecmsorder modal, long userId)
        {
            var jm = new WebApiCallBack();

            var result = UseTran(() =>
            {
                var order = Queryable().Where(o => o.OrderId == modal.OrderId && o.UserId == userId && o.OrderType == 11).First();
                if (order == null) throw new CustomException("订单不存在");
                if (order.Status == 2) 
                {
                    throw new CustomException("订单已完成，请勿重复操作");
                }
                if (order.Status == 3)
                {
                    throw new CustomException("订单已取消，请勿重复操作");
                }
                order.Status = 2;//商品收货完成
                order.ReceiveTime = DateTime.Now;
                //Update(order);

                //增加库存 修改代理成本价
                var orderItemList = Context.Queryable<Corecmsorderitem>().Where(p => p.OrderId == modal.OrderId).ToList();
                var detai = Context.Queryable<Orderdetail>().Where(d => d.OrderId == modal.OrderId).ToList();
                var productIds = orderItemList.Select(oi => oi.ProductId).ToList();

                var userStockList = Context.Queryable<Corecmsuserstock>().Where(p => p.UserId == userId && productIds.Contains(p.ProductId)).ToList();

                foreach (var product in orderItemList)
                {
                    var us = userStockList.Find(us => us.ProductId == product.ProductId);
                    if (us != null)
                    {
                        us.Stock = us.Stock.HasValue ? us.Stock + product.Nums : product.Nums;
                        us.SaleStock = us.SaleStock.HasValue ? us.SaleStock + product.Nums : product.Nums;
                        us.ProductCostPrice = product.Price;
                    }
                }
                //Context.Updateable<Corecmsuserstock>(userStockList).ExecuteCommand();
                Context.Updateable<Corecmsuserstock>(userStockList).UpdateColumns(it => new { it.Stock,it.SaleStock }).ExecuteCommand();

                var flowList = new List<StockFlowItem>();
                var dt = DateTime.Now;
                //更新产品所属关系
                var codes = detai.Select(d => d.SnCode).ToList();
                var ProdinfoList = Context.Queryable<Prodinfo>().Where(d => codes.Contains(d.SnCode)).ToList();
                foreach (var prod in ProdinfoList)
                {
                    var product = orderItemList.Where(i => i.ProductId == prod.ProductId).FirstOrDefault();
                    if (product != null)
                    {
                        //指定入库成本价
                        prod.CostPrice = product.Price;
                    }

                    prod.UserId = userId;
                    prod.Status = 1;
                    prod.InboundTime = order.SendTime;
                    prod.Agent = userId;

                    var flow = new StockFlowItem();
                    flow.UserId = userId;
                    flow.CreateTime = dt;
                    flow.SheetNo = order.OrderId;
                    flow.SnCode = prod.SnCode;
                    flow.ProductId = prod.ProductId;
                    flow.DbNo = "+";
                    flow.OrderType = 1;
                    flow.Price = product.Price;

                    flowList.Add(flow);

                }
                Context.Updateable<Prodinfo>(ProdinfoList).UpdateColumns(it => new { it.UserId, it.CostPrice, it.Status, it.InboundTime, it.Agent }).ExecuteCommand(); ;

                //写入库明细
                Context.Insertable<StockFlowItem>(flowList).ExecuteCommand(); ;

                Update(u => u.OrderId == modal.OrderId, it => new Corecmsorder()
                {
                    Status = order.Status,
                    ConfirmStatus = 2,
                    ConfirmTime = DateTime.Now,
                    UpdateTime = DateTime.Now,
                    ReceiveTime = order.ReceiveTime
                });

            });
            jm.data = modal;
            jm.status = result.IsSuccess;
            return jm;
        }


        /// <summary>
        /// 取消订单
        /// </summary>
        /// <returns></returns>
        public async Task<WebApiCallBack> CancelOrder(string[] ids, long userId = 0)
        {
            var jm = new WebApiCallBack();

            var where = Expressionable.Create<Corecmsorder>();

            where = where.And(p => ids.Contains(p.OrderId));
            where = where.And(p => p.PayStatus == (int)OrderPayStatus.No);
            where = where.And(p => p.Status == (int)OrderStatus.Confirm);
            where = where.And(p => p.ShipStatus == (int)OrderShipStatus.No);

            var msg = "代理取消操订单作";
            if (userId > 0)
            {
                where = where.And(p => p.UserId == userId);
                msg = "订单取消操作";
            }
            var orderInfo = await Queryable().Where(where.ToExpression()).ToListAsync();
            if (orderInfo != null && orderInfo.Any())
            {
                //更改状态和库存
                foreach (var item in orderInfo)
                {
                    //订单记录
                    var orderLog = new Corecmsorderlog
                    {
                        OrderId = item.OrderId,
                        UserId = item.UserId,
                        Type = (int)OrderLogTypes.LOG_TYPE_CANCEL,
                        Msg = msg,
                        Data = JsonConvert.SerializeObject(orderInfo),
                        CreateTime = DateTime.Now
                    };
                    await _orderLogServices.InsertAsync(orderLog);

                    var orderItems = await _orderItemServices.Queryable().Where(p => p.OrderId == item.OrderId).ToListAsync();
                    var user = await _corecmsuserService.GetByIdAsync(item.UserId);
                    //更改库存
                    foreach (var detail in orderItems)
                    {
                        if (item.IsMini == 1) continue;
                        _corecmsgoodsService.ChangeUserStock(detail.ProductId, user.ParentId.Value, GlobalEnumVars.OrderChangeStockType.cancel.ToString(), detail.Nums);
                    }
                }
                //状态修改
                await UpdateAsync(
                    p => new Corecmsorder()
                    {
                        Status = (int)OrderStatus.Cancel,
                        UpdateTime = DateTime.Now
                    }, p => ids.Contains(p.OrderId));

                jm.status = true;
                jm.data = orderInfo;
                jm.msg = "订单取消成功";
            }
            else
            {
                jm.msg = "订单取消失败";
            }

            return jm;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<WebApiCallBack> CancelOrderAndRefund(string orderId)
        {
            var jm = new WebApiCallBack();
            if (IsBetween0And9AM())
            {
                DateTime dt = DateTime.Now;
                //await _redisOperationRepository.SortedSetAddAsync(RedisMessageQueueKey.SmsQueue, "延时退款测试", new DateTime(dt.Year, dt.Month, dt.Day, 9, dt.Minute, dt.Second));
                jm.msg = "请9点后处理，系统这个时段正在结算，有可能退款不成功";
                return jm;
            }

            //获取订单并确认是否属于已支付并未发货的订单
            var orderInfo = Queryable().Where(p => p.OrderId == orderId && p.PayStatus == (int)OrderPayStatus.Yes && (p.Status == (int)OrderStatus.Normal || p.Status == (int)OrderStatus.Confirm || p.Status == (int)OrderStatus.pack) && p.ShipStatus == (int)OrderShipStatus.No).First();
            if (orderInfo == null)
            {
                jm.status = false;
                jm.msg = "不满足条件，必须是已支付未发货订单。";
                return jm;
            }

            //判断是否存在售后单据。
            var haveAs = _billAftersalesServices.Queryable().Where(p => p.OrderId == orderId && p.UserId == orderInfo.UserId).First();
            if (haveAs != null)
            {
                jm.msg = "存在售后单，暂不支持直接取消。";
                jm.status = false;
                return jm;
            }

            string RefundId=string.Empty;
            var orderItems = _orderItemServices.Queryable().Where(p => p.OrderId == orderId).ToList();
            var details = _orderdetailService.Queryable().Where(p => p.OrderId == orderId).ToList();

            var result = UseTran(() =>
            {
                RefundId = CommonHelper.GetSerialNumberType((int)SerialNumberType.退款单编号);
                //构建退款单
                if (orderInfo.PayedAmount > 0)
                {
                    var billRefund = new Corecmsbillrefund();
                    billRefund.RefundId = RefundId;
                    billRefund.AftersalesId = CommonHelper.GetSerialNumberType((int)SerialNumberType.售后单编号);
                    billRefund.Money = orderInfo.PayedAmount;
                    billRefund.UserId = orderInfo.UserId;
                    billRefund.SourceId = orderInfo.OrderId;
                    billRefund.Type = orderInfo.OrderType;

                    //取支付成功的支付单号
                    var paymentsInfo = _billPaymentsServices.Queryable().Where(p => p.SourceId == billRefund.SourceId && p.Type == orderInfo.OrderType && p.Status == (int)BillPaymentsStatus.Payed).First();
                    if (paymentsInfo != null)
                    {
                        billRefund.PaymentCode = paymentsInfo.PaymentCode;
                        billRefund.TradeNo = paymentsInfo.TradeNo;
                    }
                    billRefund.Status = (int)BillRefundStatus.STATUS_NOREFUND;
                    billRefund.CreateTime = DateTime.Now;

                    _billRefundServices.Insert(billRefund);
                }

                //订单记录
                var orderLog = new Corecmsorderlog
                {
                    OrderId = orderInfo.OrderId,
                    UserId = orderInfo.UserId,
                    Type = (int)GlobalEnumVars.OrderLogTypes.LOG_TYPE_CANCEL,
                    Msg = "后端操作取消订单并退款",
                    Data = JsonConvert.SerializeObject(orderInfo),
                    CreateTime = DateTime.Now
                };
                 _orderLogServices.Insert(orderLog);



                bool isupdate = Update(
                p => new Corecmsorder()
                {
                    PayStatus = (int)GlobalEnumVars.OrderPayStatus.Refunded,
                    Status = (int)GlobalEnumVars.OrderStatus.Cancel,
                    UpdateTime = DateTime.Now
                }, p => p.OrderId == orderId);

                //已经打包
                if (orderInfo.Status == (int)OrderStatus.pack)
                {
                    //处理一物一码
                    if (details != null && details.Count > 0) 
                    {
                        var codes = details.Select(d => d.SnCode).ToList();
                        var ProdinfoList = Context.Queryable<Prodinfo>().Where(d => codes.Contains(d.SnCode)).ToList();
                        foreach (var prod in ProdinfoList)
                        {
                            prod.Status = 1;
                        }
                        Context.Updateable<Prodinfo>(ProdinfoList).UpdateColumns(it => new { it.Status }).ExecuteCommand();
                        Context.Deleteable<Orderdetail>().Where(d => d.OrderId == orderInfo.OrderId).ExecuteCommand();

                    }

                    //处理订单商品
                    if (orderItems != null && orderItems.Count > 0) 
                    {
                        foreach (var item in orderItems)
                        {
                            item.SnCodes = "";
                        }
                        Context.Updateable<Corecmsorderitem>(orderItems).WhereColumns(it => new { it.Id }).UpdateColumns(it => new { it.SnCodes }).ExecuteCommand();
                    }
                }


                var user = _corecmsuserService.GetById(orderInfo.UserId);

                //更改库存
                foreach (var item in orderItems)
                {
                    _corecmsgoodsService.ChangeUserStock(item.ProductId, user.ParentId.Value, GlobalEnumVars.OrderChangeStockType.cancel.ToString(), item.Nums);
                }
            });

            if (result.IsSuccess) 
            {
                //需要退款
                if (orderInfo.PayedAmount > 0)
                {
                    await _billRefundServices.PaymentRefund(RefundId);
                }
            }

            jm.code = 0;
            jm.status = true;
            jm.data = orderInfo;
            jm.msg = "订单取消成功请前往退款单退款。";
            return jm;
        }

        /// <summary>
        /// 把退款金额和退货商品查出来判断是否能进行售后
        /// </summary>
        /// <param name="order"></param>
        /// <param name="aftersaleLevel">取售后单的时候，售后单的等级，0：待审核的和审核通过的售后单，1未审核的，2审核通过的</param>
        public void AfterSalesVal(Corecmsorder order, int aftersaleLevel = 0)
        {
            var addAftersalesStatus = false;
            var res = _billAftersalesServices.OrderToAftersales(order.OrderId, aftersaleLevel);
            var resData = res.data as OrderToAfterSalesDto;
            //已经退过款的金额
            order.refunded = resData.refundMoney;
            //已退明细
            order.afterSaleDetails = resData.afterSaleDetails;
            //算退货商品数量
            foreach (var item in order.items)
            {
                if (resData.reshipGoods.ContainsKey(item.Id))
                {
                    item.reshipNums = resData.reshipGoods[item.Id].reshipNums;
                    item.reshipedNums = resData.reshipGoods[item.Id].reshipedNums;

                    //商品总数量 - 已发货数量 - 未发货的退货数量（总退货数量减掉已发货的退货数量）
                    if (!addAftersalesStatus && (item.Nums - item.reshipNums) > 0)//如果没退完，就可以再次发起售后
                    {
                        addAftersalesStatus = true;
                    }
                }
                else
                {
                    item.reshipNums = 0;  //退货商品
                    item.reshipedNums = 0;//已发货的退货商品
                    if (!addAftersalesStatus) //没退货，就能发起售后
                    {
                        addAftersalesStatus = true;
                    }
                }
            }
            //商品没退完或没退，可以发起售后，但是订单状态不对的话，也不能发起售后
            if (order.PayStatus == (int)OrderPayStatus.No || order.Status != (int)OrderStatus.Complete)
            {
                addAftersalesStatus = false;
            }
            order.addAftersalesStatus = addAftersalesStatus;
        }

        #region 获取单个订单所有详情
        /// <summary>
        /// 根据订单编号获取单个订单所有详情
        /// </summary>
        /// <returns></returns>
        public async Task<WebApiCallBack> GetOrderInfoByOrderId(string id, long userId = 0, int aftersaleLevel = 0)
        {
            var jm = new WebApiCallBack();

            var order = new Corecmsorder();
            order = userId > 0
                ? await Queryable().Where(p => p.OrderId == id && p.UserId == userId).FirstAsync()
                : await Queryable().Where(p => p.OrderId == id).FirstAsync();
            if (order == null)
            {
                jm.msg = "获取订单失败";
                return jm;
            }
            //订单详情(子货品数据)
            order.items = await _orderItemServices.GetListAsync(p => p.OrderId == order.OrderId);
            var details = await _orderdetailService.GetListAsync(p => p.OrderId == order.OrderId);


            //售后单
            order.aftersalesItem = await _billAftersalesServices.GetListAsync(p => p.OrderId == order.OrderId && (p.Status == (int)BillAftersalesStatus.WaitAudit || p.Status == (int)BillAftersalesStatus.Success));

            //售后单取当前活动的收货单
            if (order.aftersalesItem != null && order.aftersalesItem.Any())
            {
                var aftersaleIds = order.aftersalesItem.Select(it => it.AftersalesId).ToList();

                order.afterSaleDetails = await _billaftersaledetailService.GetListAsync(d => aftersaleIds.Contains(d.AftersalesId));

                foreach (var item in order.aftersalesItem)
                {
                    order.BillAftersalesId = item.AftersalesId;
                    //如果售后单里面有待审核的活动售后单，那就直接拿这条
                    if (item.Status == (int)BillAftersalesStatus.WaitAudit) break;
                }
            }

            if (order.items.Any())
            {
                order.items.ForEach(p =>
                {
                    var extsisDetails = order.afterSaleDetails.FindAll(t => t.ProductId == p.ProductId).Select(t => t.SnCode);
                    p.Orderdetail = details.FindAll(t => t.ProductId == p.ProductId && !extsisDetails.Contains(t.SnCode));
                });
            }

            //order.items = order.items.Where(i => i.Orderdetail.Any()).ToList();
            if (!order.items.Any())
            {
                order.addAftersalesStatus = false;
                jm.msg = "不存在需要退货的商品";
                jm.status = false;
                return jm;
            }

            //如果存在未处理的售后，就不能再次发起售后
            if (order.aftersalesItem.Any() && aftersaleLevel != 2 && order.aftersalesItem.Exists(p => p.Status == (int)BillAftersalesStatus.WaitAudit))
            {
                order.addAftersalesStatus = false;
                jm.msg = "存在未处理的售后，不能再次发起售后";
                jm.status = false;
                return jm;

            }
            else
            {
                //把退款金额和退货商品查出来判断是否能进行售后
                AfterSalesVal(order, aftersaleLevel);
            }

            jm.status = true;
            jm.data = order;
            jm.msg = "";

            return jm;
        }

        #endregion

        /// <summary>
        /// 查询导出表达式
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        private static Expressionable<Corecmsorder> QueryExp(CorecmsorderQueryDto parm)
        {
            var predicate = Expressionable.Create<Corecmsorder>();

            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.orderId), it => it.OrderId == parm.orderId);
            predicate = predicate.AndIF(parm.PayStatus != null, it => it.PayStatus == parm.PayStatus);
            predicate = predicate.AndIF(parm.orderType != null, it => it.OrderType == parm.orderType);
            predicate = predicate.AndIF((parm.Status == 4), it => (it.Status == 4||it.Status==1));
            predicate = predicate.AndIF((parm.Status != null&& parm.Status != 4), it => it.Status == parm.Status);
            predicate = predicate.AndIF(parm.ReceiptType != null, it => it.ReceiptType == parm.ReceiptType);
            predicate = predicate.AndIF(parm.BeginCreateTime == null, it => it.CreateTime >= DateTime.Now.AddDays(-365).ToShortDateString().ParseToDateTime());
            predicate = predicate.AndIF(parm.BeginCreateTime != null, it => it.CreateTime >= parm.BeginCreateTime);
            predicate = predicate.AndIF(parm.EndCreateTime != null, it => it.CreateTime <= parm.EndCreateTime);
            return predicate;
        }
    }
}